home *** CD-ROM | disk | FTP | other *** search
-
- {This is my procedure for drawing DOOM-like floors for the game I am working
- on. It uses the similar triangle method, but does not work as fast as I
- would like. The problem is probably that I am using Turbo Pascal. I tried to
- optimize using assembler, but have never used it before. If anyone could
- help me speed it up, I would really appreciate it. I think this procedure runs
- at about 11-12 fps without my wall,objects procedures, at about 8 fps with
- them. The wall,objects procedures run at about 20 fps without the floor
- procedure. My goal is for a nice 15 fps with everything. All speeds are on a
- 486 DX2/66.
-
-
-
- Sorry for the sloppy code. I'll try to explain.}
-
-
-
- procedure floorcast(var player1:player);
- var
- xp,yp:integer; {some of these variables might not be needed}
- z:word;
- i:byte;
- dd:longint;
- xstep,ystep:longint;
- scrd:integer;
- finx1,finy1:longint;
- finx2,finy2:integer;
- finxd,finyd:longint;
- distance:longint;
- cc,colour:byte;
- ssofs:word;
- s3,o3,o4,s4:word;
- mapx,mapy,bmapx,bmapy:byte;
- ang:integer;
- v1,v2:longint;
- lookm:integer;
- flm:byte;
- loop:integer;
- ssinc:byte;
- zinc:word;
- hh:word;
- shade:byte;
- cos2,sin2,cos1,sin1:longint;
- sf:byte;
- begin
- v1:=viewcos^[0]; {to fix the fishbowl effect}
- v2:=viewcos^[319];
- lookm:=(player1.look-100); {to find out if the player is looking up or down}
- loop:=(player1.look+1); {number of h-lines to draw}
- hh:=(vdis)*player1.height; {viewer distance * player height}
- ang:=dangle(0,-dangle(player1.angle,(-160))); {angle for left most pixel}
- cos1:=cost^[ang]; {trig values for angle}
- sin1:=sint^[ang];
- ang:=dangle(0,-dangle(player1.angle,(160))); {angle for right most pixel}
- cos2:=cost^[ang]; {trig values for angle}
- sin2:=sint^[ang];
- ssofs:=320*loop+o1+xmin; {screen offset at start of loop}
- ssinc:=xmin+320-xmax; {screen offset increment to start each h-line}
- zinc:=xmax-xmin; {size of h-viewport}
- emsmap(handle,0,0); {ems routines for graphics}
- emsmap(handle,1,1);
- emsmap(handle,2,2);
- emsmap(handle,3,3);
- for i:=loop to toomax do {loop from horizon to bottom of screen}
- begin
- dd:=(hh div (i-player1.look)); {temp distance variable used twice}
- distance:=(dd*v1) shr 16; {fishbowl adjust}
- distance:=(distance*5) shr 2; {This fixes a strange floor shift for me}
- distance:=distance-lookm; {adjust for looking up or down}
- finx1:=((distance*cos1)) shr 16; {rotate to player angle}
- finy1:=(-(distance*sin1)) shr 16;
-
- distance:=(dd*v2) shr 16; {same as above for right most pixel}
- distance:=(distance*5) shr 2;
- distance:=distance-lookm;
- finx2:=((distance*cos2)) shr 16;
- finy2:=(-(distance*sin2)) shr 16;
-
- finxd:=(finx2-finx1); {x-distance}
- finyd:=(finy2-finy1); {y-distance}
- finx1:=finx1+player1.x; {translate to player position}
- finy1:=finy1+player1.y;
- xstep:=(finxd shl 16) div 320; {x-step along map for each pixel}
- ystep:=(finyd shl 16) div 320; {x-step along map for each pixel}
- finx1:=finx1 shl 16;
- finy1:=finy1 shl 16;
- z:=ssofs+zinc; {value for end of loop}
- finx1:=(finx1+xstep*xmin); { adjust for variable screen size}
- finy1:=(finy1+ystep*xmin);
- repeat
- if mem[s1:o1+ssofs]=0 then {if a wall or object has not been drawn}
- begin
- xp:=finx1 shr 16; {fixed point shift}
- yp:=finy1 shr 16;
- asm
- mov ax,xp {map position}
- shr ax,6
- mov mapx,al
- mov ax,yp
- shr ax,6
- mov mapy,al
- mov ax,xp {bitmap position}
- and ax,3Fh
- mov bmapx,al
- mov ax,yp
- and ax,3Fh
- mov bmapy,al
- end;
- if (mapx>25) or (mapx<=0) or (mapy>25) or (mapy<=0) then
- colour:=8 {check if out of bounds, I have a small map}
- else
- begin
- colour:=floormap^[mapx,mapy]; {else find colour in map}
- flm:=flipmap^[mapx,mapy]; {check if I should flip the bitmap}
- if flm=0 then
- begin
- end
- else if flm=1 then bmapx:=63-bmapx
- else if flm=2 then bmapy:=63-bmapy
- else if flm=3 then
- begin
- bmapx:=63-bmapx;
- bmapy:=63-bmapy;
- end;
- end;
- if bmapy>62 then bmapy:=62;
- o4:=bmapx+((bmapy) shl 6)+ctable[colour]; {find the offset of the}
- asm {pixel in the bitmap}
- mov es,[segment]
- mov bx,[o4]
- mov dl,byte ptr [es:bx] {put it on the screen}
- mov es,[s1]
- mov bx,[ssofs]
- mov byte ptr [es:bx],dl
- end;
- end;
- ssofs:=ssofs+1; {increment screen offset}
- finx1:=finx1+xstep; {step along map}
- finy1:=finy1+ystep;
- until ssofs=z; {until end of h-line}
- ssofs:=ssofs+ssinc; {move down one h-line}
- end;
- end;